/* ========================================================================= */
/* ------------------------------------------------------------------------- */
/*!
  \file			fileimpl.cc
  \date			Dec 2012
  \author		TNick

  \brief		Contains the implementation of FileImpl class


*//*


 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 Please read COPYING and README files in root folder
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
*/
/* ------------------------------------------------------------------------- */
/* ========================================================================= */
//
//
//
//
/*  INCLUDES    ------------------------------------------------------------ */

#include	<cpg/cpg.h>

#include	<cpg/actions/actionshost.h>
#include	<cpg/actions/editorbase.h>
#include	"fileimpl.h"

#include	<QCloseEvent>
#include	<QMenu>
#include	<QToolBar>
#include    <QStyleFactory>
#include    <QWhatsThis>
#include    <QSettings>
#include    <QMessageBox>
#include    <QDir>
#include    <QFileDialog>
#include    <QMdiSubWindow>

/*  INCLUDES    ============================================================ */
//
//
//
//
/*  DEFINITIONS    --------------------------------------------------------- */


/*  DEFINITIONS    ========================================================= */
//
//
//
//
/*  DATA    ---------------------------------------------------------------- */

/*  DATA    ================================================================ */
//
//
//
//
/*  CLASS    --------------------------------------------------------------- */

/* ------------------------------------------------------------------------- */
FileImpl::FileImpl		( QObject * parent )
	:QObject( parent ), MemTrack()
{
	host_ = NULL;
}
/* ========================================================================= */

/* ------------------------------------------------------------------------- */
FileImpl::~FileImpl	( void )
{
	/* stub */
}
/* ========================================================================= */

/* ------------------------------------------------------------------------- */
bool						FileImpl::init				( ActionsHost * host )
{

	host_ = host;
	ui_.setupUi( host->uiParentWidget() );

	connect(ui_.action_New,     SIGNAL(triggered()), this, SLOT(slot_New()));
	connect(ui_.action_Open,    SIGNAL(triggered()), this, SLOT(slot_Open()));
	connect(ui_.action_Save,    SIGNAL(triggered()), this, SLOT(slot_Save()));
	connect(ui_.action_SaveAs,  SIGNAL(triggered()), this, SLOT(slot_SaveAs()));
	connect(ui_.action_Close,   SIGNAL(triggered()), this, SLOT(slot_Close()) );
	connect(ui_.action_Exit,    SIGNAL(triggered()), this, SIGNAL(appEndReq()) );

	ui_.action_New->setWhatsThis( ui_.action_New->toolTip() );
	ui_.action_Open->setWhatsThis( ui_.action_Open->toolTip() );
	ui_.action_Save->setWhatsThis( ui_.action_Save->toolTip() );
	ui_.action_SaveAs->setWhatsThis( ui_.action_SaveAs->toolTip() );
	ui_.action_Close->setWhatsThis( ui_.action_Close->toolTip() );
	ui_.action_Exit->setWhatsThis( ui_.action_Exit->toolTip() );
	ui_.menuRecent_files->setWhatsThis( ui_.menuRecent_files->toolTip() );

	ui_.action_New->setStatusTip( ui_.action_New->toolTip() );
	ui_.action_Open->setStatusTip( ui_.action_Open->toolTip() );
	ui_.action_Save->setStatusTip( ui_.action_Save->toolTip() );
	ui_.action_SaveAs->setStatusTip( ui_.action_SaveAs->toolTip() );
	ui_.action_Close->setStatusTip( ui_.action_Close->toolTip() );
	ui_.action_Exit->setStatusTip( ui_.action_Exit->toolTip() );
	ui_.menuRecent_files->setStatusTip( ui_.menuRecent_files->toolTip() );

	ui_.action_New->setShortcuts( QKeySequence::keyBindings( QKeySequence::New ) );
	ui_.action_Open->setShortcuts( QKeySequence::keyBindings( QKeySequence::Open ) );
	ui_.action_Save->setShortcuts( QKeySequence::keyBindings( QKeySequence::Save ) );
	ui_.action_SaveAs->setShortcuts( QKeySequence::keyBindings( QKeySequence::SaveAs ) );
	ui_.action_Close->setShortcuts( QKeySequence::keyBindings( QKeySequence::Close ) );
	ui_.action_Exit->setShortcuts( QKeySequence::keyBindings( QKeySequence::Quit ) );

	QSettings settings;
	QString s_crt;
	settings.beginGroup("recent_files");
	rcnt_f_count = settings.value( "::count::", 10 ).toInt();
	if ( rcnt_f_count < 2)
	{
		 rcnt_f_count = 2;
	}
	else if ( rcnt_f_count > 50)
	{
		 rcnt_f_count = 50;
	}
	for (int i = 0; i < rcnt_f_count; i++)
	{
		s_crt = settings.value(QString(i), "").toString();
		if (s_crt.isEmpty())
			break;
		rcnt_f.append(s_crt);
	}

	connect(ui_.menuRecent_files, SIGNAL(triggered(QAction*)),
			this,SLOT(slot_RecentFile(QAction*)));

	settings.endGroup();
	slot_UpdateRcFilesMenu();


	activeEditorChanged( NULL );
	return true;
}
/* ========================================================================= */

/* ------------------------------------------------------------------------- */
void						FileImpl::end					( void )
{
	QSettings settings;

	/* recent files initialization */
	int       i;

	if ( rcnt_f_count < 2)
	{
		 rcnt_f_count = 2;
	}
	else if ( rcnt_f_count > 50)
	{
		 rcnt_f_count = 50;
	}
	PGDBG2( PGDBG_A_FILE, "  - number of recent files to save",
			 rcnt_f_count );


	settings.beginGroup("recent_files");
	settings.setValue("::count::",  rcnt_f_count);
	for (i = 0; i <  rcnt_f_count; i++)
	{
		if (i >=  rcnt_f.count())
			break;
		settings.setValue(QString(i),  rcnt_f.at(i));
	}
	PGDBG2( PGDBG_A_FILE, "  - number of recent files saved", i );

	settings.setValue(QString(i), "");
	settings.endGroup();
}
/* ========================================================================= */

/* ------------------------------------------------------------------------- */
void						FileImpl::initMenu				( QMenu * menu )
{
	menu->addAction( ui_.action_New );
	menu->addAction( ui_.action_Open );
	menu->addMenu( ui_.menuRecent_files );
	menu->addSeparator();
	menu->addAction( ui_.action_Save );
	menu->addAction( ui_.action_SaveAs );
	menu->addSeparator();
	menu->addAction( ui_.action_Close );
	menu->addSeparator();
	menu->addAction( ui_.action_Exit );

}
/* ========================================================================= */

/* ------------------------------------------------------------------------- */
void						FileImpl::initToolbar			( QToolBar * tb )
{
	tb->addAction( ui_.action_New );
	tb->addAction( ui_.action_Open );
	tb->addSeparator();
	tb->addAction( ui_.action_Save );
	tb->addSeparator();
	tb->addAction( ui_.action_Close );
}
/* ========================================================================= */

/* ------------------------------------------------------------------------- */
void        				FileImpl::slot_Close            	( void )
{
	PGDBG2( PGDBG_A_FILE, "FileImpl: close document", this );

	EditorBase * ed = host_->crtEditor();
	PGDBG2( PGDBG_A_FILE, "  - document", ed );

	emit editorCloseReq( ed );
}
/* ========================================================================= */

/* ------------------------------------------------------------------------- */
void        				FileImpl::slot_New            	( void )
{
	PGDBG2( PGDBG_A_FILE, "FileImpl: new document", this );

	EditorImpl * ed = new EditorImpl();
	PGDBG2( PGDBG_A_FILE, "  - created instance", ed );

	ed->fileNew();
	emit editorCreated( ed );
}
/* ========================================================================= */

/* ------------------------------------------------------------------------- */
bool        				FileImpl::slot_Open            	(
		const QString & s_file, const QString & loc )
{
	EditorImpl * ed = new EditorImpl();
	PGDBG2( PGDBG_A_FILE, "  - created instance", ed );

	if ( ed->fileOpen( s_file, loc ) )
	{
		emit editorCreated( ed );
		return true;
	}
	else
	{
		delete ed;
		return false;
	}
}
/* ========================================================================= */

/* ------------------------------------------------------------------------- */
bool        				FileImpl::slot_Open            	(
		const QString & s_file )
{
	EditorImpl * ed = new EditorImpl();
	PGDBG2( PGDBG_A_FILE, "  - created instance", ed );

	if ( ed->fileOpen( s_file ) )
	{
		emit editorCreated( ed );
		return true;
	}
	else
	{
		delete ed;
		return false;
	}
}
/* ========================================================================= */

/* ------------------------------------------------------------------------- */
bool        				FileImpl::slot_Open            	( void )
{
	PGDBG2( PGDBG_A_FILE, "FileImpl: open document", this );

	QFileDialog::Options options;
	QString			selectedFilter = "*.cpg";
	QString &		s_dir_crt = host_->crtDirectory();
	QString s_file = QFileDialog::getOpenFileName(
				host_->uiParentWidget(),
				tr("Select the file to open..."),
				s_dir_crt,
				tr("cad-play-ground files (*.cpg);;All Files (*)"),
				&selectedFilter,
				options);
	PGDBG2( PGDBG_A_FILE, "  - choice: ", s_file );
	if ( !s_file.isEmpty() )
	{
		s_dir_crt = QFileInfo( s_file ).absolutePath();
		if ( slot_Open( s_file ) == false )
		{
			QMessageBox::warning(
						host_->uiParentWidget(), tr( "Error opening file" ),
						tr( "The file %1\ncould not be opened." )
						.arg( s_file ),
						QMessageBox::Ok );
			return false;
		}
		return true;
	}
	else
	{
		PGDBG( PGDBG_A_FILE, "  - user cancelled the open command" );
		return false;
	}
}
/* ========================================================================= */

/* ------------------------------------------------------------------------- */
void        				FileImpl::slot_Save            	( void )
{
	PGDBG2( PGDBG_A_FILE, "FileImpl: save document", this );

	EditorBase * ed = host_->crtEditor();
	PGDBG2( PGDBG_A_FILE, "  - document", ed );

	emit editorSaveReq( ed );
}
/* ========================================================================= */

/* ------------------------------------------------------------------------- */
void        				FileImpl::slot_SaveAs            	( void )
{
	PGDBG2( PGDBG_A_FILE, "FileImpl: save document as ", this );

	EditorBase * ed = host_->crtEditor();
	PGDBG2( PGDBG_A_FILE, "  - document", ed );

	emit editorSaveAsReq( ed );
}
/* ========================================================================= */

/* ------------------------------------------------------------------------- */
void						FileImpl::activeEditorChanged		( EditorBase * ed )
{
	bool with_file = ( ed != NULL );

	ui_.action_Save->setEnabled( with_file );
	ui_.action_SaveAs->setEnabled( with_file );
	ui_.action_Close->setEnabled( with_file );

}
/* ========================================================================= */

/* ------------------------------------------------------------------------- */
void						FileImpl::slot_RecentFile         ( QAction * p_active )
{
	PGDBG2( PGDBG_A_FILE, "FileImpl: open recent file", this );

	QList<QAction *> acls =	ui_.menuRecent_files->actions();
	int i = acls.indexOf(p_active);
	if (i < 0)
		return;
	if (i >= rcnt_f.count())
		return;
	PGDBG2( PGDBG_A_FILE, "  - index", i );

	if ( slot_Open( rcnt_f.at( i ) ) == false )
	{
        int j = QMessageBox::warning(
					host_->uiParentWidget(), tr( "Error opening file" ),
                    tr(
                        "The file %1\ncould not be opened.\n"
                        "\n"
                        "Should it be removed from the list "
                        "of recent files?"
                        )
					.arg( rcnt_f.at( i ) ),
                    QMessageBox::Yes | QMessageBox::No );
        if ( j == QMessageBox::Yes )
        {
            rcnt_f.removeAt( i );
            slot_UpdateRcFilesMenu();
        }
	}
}
/* ========================================================================= */

/* ------------------------------------------------------------------------- */
void        FileImpl::slot_UpdateRcFilesMenu  ( void )
{
	ui_.menuRecent_files->clear();

	if (rcnt_f.count() == 0)
	{
		ui_.menuRecent_files
				->addAction( tr("(none)") )
				->setEnabled( false );
		return;
	}

	for (int i = 0; i < rcnt_f.count(); ++i)
	{
		QAction *action  =	ui_.menuRecent_files->addAction(
					QFileInfo(rcnt_f.at(i)).fileName());
		action->setToolTip(rcnt_f.at(i));
	}

}
/* ========================================================================= */

/* ------------------------------------------------------------------------- */
void        FileImpl::addRecentFile           ( EditorBase * ed )
{
	if ( ed->isUntitled() )
		return;
	QString s_file = ed->filePath();
	if ( s_file.isEmpty() )
		return;

	int i = rcnt_f.indexOf( s_file );
	if (i != -1)
	{
		rcnt_f.move(i, 0);
	}
	else
	{
		if (rcnt_f.count() >= rcnt_f_count)
		{
			rcnt_f.removeLast();
		}
		rcnt_f.prepend(s_file);
	}
	slot_UpdateRcFilesMenu();
}
/* ========================================================================= */

/*  CLASS    =============================================================== */
//
//
//
//
/* ------------------------------------------------------------------------- */
/* ========================================================================= */
